主要與strategies.sol互動
A helper library to create deterministic clones of the strategy contracts when a pool is created
library Clone {
function createClone(address _contract, uint256 _nonce) internal returns (address) {
bytes32 salt = keccak256(abi.encodePacked(msg.sender, _nonce));
return ClonesUpgradeable.cloneDeterministic(_contract, salt);
}
}
處理所有Revert
contract Errors {
/// ======================
/// ====== Generic =======
/// ======================
error INVALID();
error MISMATCH();
error NOT_ENOUGH_FUNDS();
error UNAUTHORIZED();
error ZERO_ADDRESS();
/// ======================
/// ====== Registry ======
/// ======================
/// @dev Thrown when the nonce passed has been used or not available
error NONCE_NOT_AVAILABLE();
/// @dev Thrown when the 'msg.sender' is not the pending owner on ownership transfer
error NOT_PENDING_OWNER();
/// @dev Thrown if the anchor creation fails
error ANCHOR_ERROR();
/// ======================
/// ======== Allo ========
/// ======================
/// @notice Thrown when the strategy is not approved
error NOT_APPROVED_STRATEGY();
/// @notice Thrown when the strategy is approved and should be cloned
error IS_APPROVED_STRATEGY();
/// @notice Thrown when the fee is below 1e18 which is the fee percentage denominator
error INVALID_FEE();
/// ======================
/// ===== IStrategy ======
/// ======================
error ALREADY_INITIALIZED();
error NOT_INITIALIZED();
error INVALID_ADDRESS();
error POOL_INACTIVE();
error POOL_ACTIVE();
error ARRAY_MISMATCH();
error INVALID_REGISTRATION();
error INVALID_METADATA();
error RECIPIENT_NOT_ACCEPTED();
error RECIPIENT_ALREADY_ACCEPTED();
error REGISTRATION_NOT_ACTIVE();
error RECIPIENT_ERROR(address recipientId);
error ALLOCATION_NOT_ACTIVE();
error ALLOCATION_NOT_ENDED();
error ALLOCATION_ACTIVE();
}
Metadata is used to define the metadata for the protocol that is used throughout the system.
定義一個Struct 包含Protocol(IPFS = 1) 及 pointer
struct Metadata {
/// @notice Protocol ID corresponding to a specific protocol (currently using IPFS = 1)
uint256 protocol;
/// @notice Pointer (hash) to fetch metadata for the specified protocol
string pointer;
}
This is used to define the address of the native token for the protocol
address public constant NATIVE = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
A helper contract to transfer tokens within Allo protocol
引入 上面的Native.sol 及utils/SafeTransferLib.sol
contract Transfer is Native {
/// @notice Thrown when the amount of tokens sent does not match the amount of tokens expected
error AMOUNT_MISMATCH();
/// @notice This holds the details for a transfer
struct TransferData {
address from;
address to;
uint256 amount;
}
/// Transfer an amount of a token to an array of addresses
function _transferAmountsFrom(address _token, TransferData[] memory _transferData) internal returns (bool) {
uint256 msgValue = msg.value;
for (uint256 i; i < _transferData.length;) {
TransferData memory transferData = _transferData[i];
if (_token == NATIVE) {
msgValue -= transferData.amount;
SafeTransferLib.safeTransferETH(transferData.to, transferData.amount);
} else {
SafeTransferLib.safeTransferFrom(_token, transferData.from, transferData.to, transferData.amount);
}
unchecked {
i++;
}
}
if (msgValue != 0) revert AMOUNT_MISMATCH();
return true;
}
/// Transfer an amount of a token to an address
function _transferAmountFrom(address _token, TransferData memory _transferData) internal returns (bool) {
uint256 amount = _transferData.amount;
if (_token == NATIVE) {
// Native Token
if (msg.value < amount) revert AMOUNT_MISMATCH();
SafeTransferLib.safeTransferETH(_transferData.to, amount);
} else {
SafeTransferLib.safeTransferFrom(_token, _transferData.from, _transferData.to, amount);
}
return true;
}
/// Transfer an amount of a token to an address
function _transferAmount(address _token, address _to, uint256 _amount) internal {
if (_token == NATIVE) {
SafeTransferLib.safeTransferETH(_to, _amount);
} else {
SafeTransferLib.safeTransfer(_token, _to, _amount);
}
}
}
struct TransferData {
address from;
address to;
uint256 amount;
}
引用昨天提到的CREATE3
contractFactory is used internally to deploy our contracts using CREATE3
contract ContractFactory {
/// ======================
/// ======= Errors =======
/// ======================
/// Thrown when the requested salt has already been used.
error SALT_USED();
/// Thrown when the caller is not authorized to deploy.
error UNAUTHORIZED();
/// ======================
/// ======= Events =======
/// ======================
/// Emitted when a contract is deployed.
event Deployed(address indexed deployed, bytes32 indexed salt);
/// ======================
/// ======= Storage ======
/// ======================
/// Collection of used salts.
mapping(bytes32 => bool) public usedSalts;
/// Collection of authorized deployers.
mapping(address => bool) public isDeployer;
/// ======================
/// ======= Modifiers ====
/// ======================
/// Modifier to ensure the caller is authorized to deploy and returns if not.
modifier onlyDeployer() {
_checkIsDeployer();
_;
}
/// ======================
/// ===== Constructor ====
/// ======================
/// On deployment sets the 'msg.sender' to allowed deployer.
constructor() {
isDeployer[msg.sender] = true;
}
/// ===============================
/// ====== Internal Functions =====
/// ===============================
/// Checks if the caller is authorized to deploy.
function _checkIsDeployer() internal view {
if (!isDeployer[msg.sender]) revert UNAUTHORIZED();
}
/// ===============================
/// ====== External Functions =====
/// ===============================
/// eploys a contract using CREATE3.
function deploy(string memory _contractName, string memory _version, bytes memory creationCode)
external
payable
onlyDeployer
returns (address deployedContract)
{
// hash salt with the contract name and version
bytes32 salt = keccak256(abi.encodePacked(_contractName, _version));
// ensure salt has not been used
if (usedSalts[salt]) revert SALT_USED();
usedSalts[salt] = true;
deployedContract = CREATE3.deploy(salt, creationCode, msg.value);
emit Deployed(deployedContract, salt);
}
/// Set the allowed deployer.
function setDeployer(address _deployer, bool _allowedToDeploy) external onlyDeployer {
// Set the deployer to the allowedToDeploy mapping
isDeployer[_deployer] = _allowedToDeploy;
}
}
好好了解Uniswap V1->V2->V3->V4,未來(這次鐵人賽結束)可以繼續了解常用Web3工具合約(主要是gnosis safe)